package cn.zwx.member.svc.rpc;

import cn.zwx.base.entity.ResponseEntity;
import cn.zwx.base.exception.BizWrapException;
import cn.zwx.base.utils.ValidationUtils;
import cn.zwx.member.svc.domain.constans.MemberConstans;
import cn.zwx.member.svc.domain.entity.AddressEntity;
import cn.zwx.member.svc.domain.entity.DistrictsEntity;
import cn.zwx.member.svc.domain.enums.AddressTyepEnum;
import cn.zwx.member.svc.domain.enums.MemberCodeEnum;
import cn.zwx.member.svc.domain.warp.AddressWrap;
import cn.zwx.member.svc.domain.warp.ExceptionWrap;
import cn.zwx.member.svc.rpc.dto.InsertAddressDTO;
import cn.zwx.member.svc.rpc.dto.UpdateAddressDTO;
import cn.zwx.member.svc.rpc.facade.DubboAddressService;
import cn.zwx.member.svc.rpc.vo.AddressVO;
import cn.zwx.member.svc.service.AddressService;
import cn.zwx.member.svc.service.DistrictsService;
import org.apache.dubbo.apidocs.annotations.ApiDoc;
import org.apache.dubbo.apidocs.annotations.ApiModule;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhangwenxue
 * ApiModule 必要 api-doc会查找所有带有@ApiModule的bean对象
 */
@Service
@ApiModule(value = "用户地址相关接口", apiInterface = DubboAddressService.class)
@DubboService(version = "v1.0.0",interfaceClass = DubboAddressService.class,timeout = 8000)
public class DubboAddressServiceImpl  implements DubboAddressService {

    @Resource
    private AddressService addressService;

    @Resource
    private DistrictsService districtsService;


    @Override
    @ApiDoc(value = "根据主键id查询地址信息接口")
    public ResponseEntity<AddressVO> queryById(@NotNull(message = "地址id不能为空") Long id)  throws BizWrapException {
        // 1.验证参数
        ValidationUtils.getInstance().validate(id);
        // 2.查询地址信息
        final AddressEntity addressEntity = addressService.selectById(id);
        if (Objects.isNull(addressEntity)){
            throw ExceptionWrap.wrap(MemberCodeEnum.NOT_QUERY_ADDRESS_EXIST_ERROR);
        }
        // 3.封装返回参数
        final AddressVO addressVO = new AddressVO();
        BeanUtils.copyProperties(addressEntity,addressVO);
        addressVO.setIsDefault(addressEntity.getIsDefault() == AddressTyepEnum.DEFAULT_.getCode()?Boolean.TRUE:Boolean.FALSE);
        return ResponseEntity.success(addressVO);
    }

    @Override
    @ApiDoc(value = "根据用户id查询地址信息接口")
    public ResponseEntity<List<AddressVO>> selectByUserId(@NotBlank(message = "用户id不能为空") String userId) {
        List<AddressVO> returnList = new ArrayList<>();
        // 1.查询地址信息
        final List<AddressEntity> entityList = addressService.selectByUserId(userId);
        // 2.返回封装信息
        if (CollectionUtils.isEmpty(entityList)){
            return ResponseEntity.success(returnList);
        }
        entityList.forEach(t->{
            final AddressVO addressVO = new AddressVO();
            BeanUtils.copyProperties(t,addressVO);
            addressVO.setIsDefault(t.getIsDefault() == AddressTyepEnum.DEFAULT_.getCode()?Boolean.TRUE:Boolean.FALSE);
            returnList.add(addressVO);
        });
        return ResponseEntity.success(returnList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ApiDoc(value = "添加用户地址接口")
    public ResponseEntity<Long> insert(@Validated  InsertAddressDTO address)throws BizWrapException {
        // 1.验证地址是否存在
        boolean isExistState = addressService.checkUserAddressExists(AddressWrap.wrap(address));
        if (isExistState){
            throw ExceptionWrap.wrap(MemberCodeEnum.ADDRESS_EXIST_ERROR);
        }
        // 2.查询地址信息
        final List<Long> distictsIdList = new ArrayList<>();
        distictsIdList.add(address.getProvinceId());
        distictsIdList.add(address.getCityId());
        distictsIdList.add(address.getDistrictId());
        List<DistrictsEntity> distictsList =  districtsService.getByIdList(distictsIdList);
        if (distictsIdList.size() != distictsList.size()){
            throw ExceptionWrap.wrap(MemberCodeEnum.ADDRESS_NOT_EXIST_ERROR);
        }
        final Map<Integer, DistrictsEntity> districtsEntityMap = distictsList.stream().collect(Collectors.toMap(DistrictsEntity::getDistrictId,
                Function.identity(), (key1, key2) -> key2));
        // 3.插入地址信息 取消
        if (address.getIsDefault()){
            addressService.cancelUserDefaultAddress(address.getUserId());
        }
        final AddressEntity addressEntity = new AddressEntity();
        addressEntity.setUpdateTime(new Date());
        addressEntity.setCreateTime(new Date());
        final Boolean isDefault = address.getIsDefault();
        addressEntity.setIsDefault(isDefault? AddressTyepEnum.DEFAULT_.getCode():AddressTyepEnum.NORMAL.getCode());
        addressEntity.setAddress(address.getAddress());
        addressEntity.setContact(address.getContact());
        addressEntity.setCityId(address.getCityId().toString());
        addressEntity.setCityName(districtsEntityMap.get(address.getDistrictId().intValue()).getName());
        addressEntity.setProvinceId(address.getProvinceId().toString());
        addressEntity.setProvinceName(districtsEntityMap.get(address.getProvinceId().intValue()).getName());
        addressEntity.setDistrictId(address.getDistrictId().toString());
        addressEntity.setDistrictName(districtsEntityMap.get(address.getDistrictId().intValue()).getName());
        addressEntity.setPhone(address.getPhone());
        addressEntity.setUserId(address.getUserId());
        addressService.insert(addressEntity);
        return ResponseEntity.success(addressEntity.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ApiDoc(value = "修改用户地址接口")
    public ResponseEntity<Void> update(@Validated  UpdateAddressDTO address)throws BizWrapException {
        // 1.查询是否存在
        final AddressEntity addressEntity = addressService.selectById(address.getId());
        if (ObjectUtils.isEmpty(addressEntity)){
            throw ExceptionWrap.wrap(MemberCodeEnum.ADDRESS_NOT_EXIST_ERROR);
        }
        // 2.查询地址信息
        final List<Long> distictsIdList = new ArrayList<>();
        if (!ObjectUtils.isEmpty(address.getProvinceId())){
            distictsIdList.add(address.getProvinceId());
        }
        if (!ObjectUtils.isEmpty(address.getCityId())){
            distictsIdList.add(address.getCityId());
        }
        if (!ObjectUtils.isEmpty(address.getDistrictId())){
            distictsIdList.add(address.getDistrictId());
        }
        Map<Integer, DistrictsEntity> districtsEntityMap = new HashMap<>(MemberConstans.INT_16);
        if (!CollectionUtils.isEmpty(distictsIdList)){
            List<DistrictsEntity> distictsList =  districtsService.getByIdList(distictsIdList);
            districtsEntityMap = distictsList.stream().collect(Collectors.toMap(DistrictsEntity::getDistrictId,
                    Function.identity(), (key1, key2) -> key2));
        }
        // 3.修改信息
        this.doModifyAddress(address, addressEntity, districtsEntityMap);
        // 4.返回参数
        return ResponseEntity.success();
    }

    private void doModifyAddress(UpdateAddressDTO address, AddressEntity addressEntity, Map<Integer, DistrictsEntity> districtsEntityMap) {
        final AddressEntity updateEntity = new AddressEntity();
        if (!ObjectUtils.isEmpty(address.getIsDefault()) && address.getIsDefault()){
            addressService.cancelUserDefaultAddress(addressEntity.getUserId());
        }
        updateEntity.setUpdateTime(new Date());
        final Boolean isDefault = address.getIsDefault();
        if (!ObjectUtils.isEmpty(address.getIsDefault())){
            updateEntity.setIsDefault(isDefault? AddressTyepEnum.DEFAULT_.getCode():AddressTyepEnum.NORMAL.getCode());
        }
        updateEntity.setAddress(address.getAddress());
        updateEntity.setContact(address.getContact());
        if (!ObjectUtils.isEmpty(address.getCityId())){
            updateEntity.setCityId(address.getCityId().toString());
            updateEntity.setCityName(districtsEntityMap.get(address.getDistrictId().intValue()).getName());
        }
        if (!ObjectUtils.isEmpty(address.getProvinceId())){
            updateEntity.setProvinceId(address.getProvinceId().toString());
            updateEntity.setProvinceName(districtsEntityMap.get(address.getProvinceId().intValue()).getName());
        }
        if (!ObjectUtils.isEmpty(address.getDistrictId())){
            updateEntity.setDistrictId(address.getDistrictId().toString());
            updateEntity.setDistrictName(districtsEntityMap.get(address.getDistrictId().intValue()).getName());
        }
        updateEntity.setPhone(address.getPhone());
        updateEntity.setId(address.getId());
        addressService.modify(updateEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ApiDoc(value = "删除用户地址接口")
    public ResponseEntity<Void> delete(@Validated  Long id) {
        addressService.delete(id);
        return ResponseEntity.success();
    }
}
